package com.yumingjaing.stream;

import com.yumingjaing.mockito.MapMockito;
import com.yumingjaing.mockito.Student;
import org.junit.Test;

import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @description:
 * @author: John
 * @version: CollectionStream01Test.java, v1.0 2024年08月31日 23:12
 */
public class CollectionStream01Test {

    /**
     * 集合遍历
     */
    @Test
    public void t1() {
        MapMockito.map
                .forEach((k, v) -> System.out.println(k + ":" + v)
                );
    }

    /**
     * 从流中获取集合数量
     */
    @Test
    public void t2() {
        System.out.println(MapMockito.map
                .entrySet()
                .stream()
                .count()
        );
    }

    /**
     * 过滤掉value！=one的集合元素，然后输出数量
     */
    @Test
    public void t3() {
        System.out.println(MapMockito.map.entrySet()
                .stream()
                .filter(e -> Objects.equals(e.getValue(), "one"))
                .count());
    }

    /**
     * 过滤掉value！=one的集合元素，遍历集合
     */
    @Test
    public void t4() {
        MapMockito.map.entrySet()
                .stream()
                .filter(e -> !Objects.equals(e.getValue(), "two"))
                .limit(2)
                .forEach(
                    integerStringEntry -> {
                        System.out.println(integerStringEntry.getKey() + ":" + integerStringEntry.getValue());
                }
        );
    }

    /**
     * 过滤掉value！=one的集合元素，然后将剩下的元素跳过2后输出其他的元素
     */
    @Test
    public void t5() {
        MapMockito.map.entrySet()
                .stream()
                .filter(e -> !Objects.equals(e.getValue(), "one"))
                .limit(3)
                .skip(2).forEach(
                        integerStringEntry -> {
                            System.out.println(integerStringEntry.getKey() + ":" + integerStringEntry.getValue());
                        }
                );
    }

    /**
     * map集合中获取key,然后输出
     */
    @Test
    public void t6() {
        MapMockito.map.entrySet()
                .stream()
                .filter(e -> !Objects.equals(e.getValue(), "one"))
                .limit(3)
                .map(Map.Entry::getKey)
                .toList()
                .forEach(System.out::println);
    }

    /**
     * map 排序
     */
    @Test
    public void t7() {
        MapMockito.map.entrySet()
                .stream()
                .filter(e -> !Objects.equals(e.getValue(), "one"))
                .limit(3)
                .map(Map.Entry::getKey)
                .sorted()
                .forEach(System.out::println);
    }

    /**
     * 去重
     */
    @Test
    public void t8() {
        MapMockito.mapString
                .values()
                .stream()
                .distinct()
                .forEach(System.out::println);
    }

    /**
     * 判断集合里面是否有匹配的数据
     */
    @Test
    public void t9() {
        boolean one = MapMockito.mapString.values()
                .stream()
                .distinct()
                .anyMatch(Predicate.isEqual("one"));
        System.out.println(one);

    }

    @Test
    public void t10() {
        MapMockito.mapString.values()
                .stream()
                .findAny()
                .ifPresent(System.out::println);
    }

    /**
     * 串行流输出
     */
    @Test
    public void t11() {
        MapMockito.map.keySet()
                .stream()
                .max(new IntegerComparator())
                .ifPresent(System.out::println);
    }

    /**
     * 并行流输出
     */
    @Test
    public void t12() {
        MapMockito.mapString.values()
                .parallelStream()
                .forEach(v -> {System.out.println(Thread.currentThread().getName() + "-->" + v);});
    }

    /**
     * 数据分组
     */
    @Test
    public void t13() {
        Stream<Student> studentStream = Stream.of(
                new Student("zhangsan", 21, 60),
                new Student("lisi", 22, 60),
                new Student("wangwu", 38, 57),
                new Student("laoliu", 56, 100),
                new Student("laoqi", 22, 30),
                new Student("sanba", 38, 99)
        );

        Map<Integer, Map<String, List<Student>>> collect = studentStream
                .collect(Collectors.groupingBy(Student::getAge, Collectors.groupingBy(student -> {
                    if (student.getScore() == 100) {
                        return "waw!!!";
                    } else if (student.getScore() >= 90 && student.getScore() < 100) {
                        return "nice!!!";
                    } else if (student.getScore() >= 60 && student.getScore() < 90) {
                        return "good!!!";
                    } else {
                        return "finding!!!";
                    }
                })));

        collect.forEach((k, v) -> {
            System.out.println(k + "==" + v);
        });
    }
}

/**
 * Integer比较器
 */
class IntegerComparator implements Comparator<Integer> {
    @Override
    public int compare(Integer o1, Integer o2) {
        return Integer.min(o1, o2);
    }
}